package net.cnki.sunny.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import net.cnki.sunny.base.BaseService;
import net.cnki.sunny.model.dto.OperateLogDTO;
import net.cnki.sunny.model.dto.StatisticsDTO;
import net.cnki.sunny.model.entity.OperateLog;
import net.cnki.sunny.model.enums.OperateLogEnums;
import net.cnki.sunny.model.mapper.OperateLogMapper;
import net.cnki.sunny.model.vo.OperateLogStatisticsVO;
import net.cnki.sunny.model.vo.StatisticsVO;
import net.cnki.sunny.service.OperateLogService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OperateLogServiceImpl extends BaseService<OperateLog> implements OperateLogService {

    @Resource
    private OperateLogMapper operateLogMapper;

    @Override
    public Integer addOperateLog(OperateLog operateLog) {
        return insert(operateLog);
    }

    @Override
    public PageInfo<OperateLog> selectByCondition(OperateLogDTO operateLogDTO) {
        PageHelper.startPage(operateLogDTO.getPageNum(), operateLogDTO.getPageSize());
        return new PageInfo<>(operateLogMapper.selectByCondition(operateLogDTO));
    }

    @Override
    public StatisticsVO statisticsOperateLog(StatisticsDTO statisticsDTO) {
        StatisticsVO statisticsVO = new StatisticsVO();
        //默认查询7条
        Integer count = 6;
        //默认当前时间
        Calendar calendar = Calendar.getInstance();
        Date endTime = calendar.getTime();
        calendar.add(Calendar.DAY_OF_YEAR, -count);
        Date startTime = calendar.getTime();
        //默认查询天
        String format = "YYYY-MM-dd", dateUnitStr = "日";
        Integer dateType = Calendar.DAY_OF_YEAR;
        //如果选择了时间范围，重置当前时间，查询条数
        if (!ObjectUtils.isEmpty(statisticsDTO.getStartTime()) && !ObjectUtils.isEmpty(statisticsDTO.getEndTime())) {
            endTime = statisticsDTO.getEndTime();
            startTime = statisticsDTO.getStartTime();
            //选择时间后年月日选择生效
            dateType = Optional.ofNullable(statisticsDTO.getDateType()).orElse(Calendar.DAY_OF_YEAR);
            if (dateType.equals(Calendar.YEAR)) {
                format = "YYYY";
                dateUnitStr = "年";
            } else if (dateType.equals(Calendar.MONTH)) {
                format = "YYYY-MM";
                dateUnitStr = "月";
            }
            if (dateType.equals(Calendar.YEAR)) {
                count = new Long(DateUtil.betweenYear(statisticsDTO.getStartTime(), statisticsDTO.getEndTime(), false)).intValue();
            } else if (dateType.equals(Calendar.MONTH)) {
                count = new Long(DateUtil.betweenMonth(statisticsDTO.getStartTime(), statisticsDTO.getEndTime(), false)).intValue();
            } else {
                count = new Long(DateUtil.betweenDay(statisticsDTO.getStartTime(), statisticsDTO.getEndTime(), false)).intValue();
            }
        }
        //查询条件
        OperateLogDTO condition = new OperateLogDTO();
        condition.setEndTime(endTime);
        condition.setStartTime(startTime);
        condition.setDateType(dateType);
        List<OperateLogStatisticsVO> operateLogStatisticsVOS = operateLogMapper.statisticsOperateLog(condition);
        //机构化数据
        //先按类型分组
        Map<Integer, List<OperateLogStatisticsVO>> collect = operateLogStatisticsVOS.stream().collect(Collectors.groupingBy(OperateLogStatisticsVO::getOperateType));
        List<StatisticsVO.Axis<Integer>> series = new ArrayList<>();
        for (OperateLogEnums.OperateType operateType : OperateLogEnums.OperateType.values()) {
            StatisticsVO.Axis axis = statisticsVO.new Axis();
            axis.setName(operateType.getName());
            List<OperateLogStatisticsVO> operateLogByType = collect.get(operateType.getCode());
            //类型下按时间分组
            if (CollectionUtils.isEmpty(operateLogByType)) {
                axis.setData(new ArrayList(Arrays.asList(0, 0, 0, 0, 0, 0, 0)));
            } else {
                Map<String, List<OperateLogStatisticsVO>> operateLogByTime = operateLogByType.stream().collect(Collectors.groupingBy(OperateLogStatisticsVO::getOperateTime));
                Integer flag = count;
                Calendar calendarCur = Calendar.getInstance();
                calendarCur.setTime(endTime);
                calendarCur.add(dateType, -flag);
                List<Integer> dataList = new ArrayList<>();
                while (flag >= 0) {
                    String dateStr = DateUtil.format(calendarCur.getTime(), format);
                    List<OperateLogStatisticsVO> operateLog = operateLogByTime.get(dateStr);
                    if (CollectionUtils.isEmpty(operateLog)) {
                        dataList.add(0);
                    } else {
                        dataList.add(operateLog.get(0).getCount());
                    }
                    flag--;
                    calendarCur.add(dateType, 1);
                }
                axis.setData(dataList);
            }
            series.add(axis);
        }
        statisticsVO.setSeries(series);
        StatisticsVO.Axis<String> xAxis = statisticsVO.new Axis<>();
        List<String> xAxisData = new ArrayList<>();
        Calendar xAxisCalendar = Calendar.getInstance();
        xAxisCalendar.add(dateType, -count);
        while (count >= 0) {
            String dateStr = DateUtil.format(xAxisCalendar.getTime(), format);
            xAxisData.add(dateStr);
            count--;
            xAxisCalendar.add(dateType, 1);
        }
        xAxis.setName("时间/" + dateUnitStr);
        xAxis.setData(xAxisData);
        statisticsVO.setXAxis(xAxis);
        return statisticsVO;
    }
}
